<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <h1 ref="h1">生命周期</h1>
    <p ref="p">count: {{count}}</p>
    <button @click="count++">btn</button>

    <hr>

    <button @click="str = 'child1'">child1</button>
    <button @click="str = 'child2'">child2</button>
    <component :is="str"></component>
  </div>

  <script src="../Vue.js"></script>

  <script>
    const { createApp } = Vue;

    const Child1 = {
      template: `
        <div>这是child1组件</div>
      `
    }

    const Child2 = {
      data() {
        return {
          num: 10,
          timer: null
        }
      },
      template: `
        <div>这是child2组件 - {{ num }}</div>
      `,
      mounted() {
        this.timer = setInterval(() => {
          console.log(123);
          this.num++
        }, 1000)

        // window.addEventListener("scroll", () => {})
      },
      beforeUnmount() {
        console.log("child2 beforeUnmount");
        clearInterval(this.timer)
      },
      unmounted() {
        console.log("child2 unmounted");
      }
    }

    createApp({
      data() {
        return {
          count: 1,
          list: [],
          str: "child1"
        }
      },

      components: {
        Child1,
        Child2
      },

      // 所有的生命周期，都是选项
      // 生命周期的函数，会自动执行
      // 生命周期的执行顺序跟写的顺序无关，只跟名字有关
      // 并不是所有的生命周期函数都会自动全部执行的，只有创建阶段和挂载阶段的会自动执行
      // 更新阶段的生命周期需要在组件的数据发生改变以后会执行
      // 销毁阶段的生命周期需要在组件被销毁时执行

      // 创建阶段
      beforeCreate() {
        // 在beforeCreate里面拿不到任何和选项式api相关的内容
        // 不能在这里请求数据，请求到了之后也不好赋值
        // 获取一些url相关的信息（也会有更好的选择）
        console.log("beforeCreate", this.count);
        // fetch("https://cnodejs.org/api/v1/topics")
        //   .then(response => response.json())
        //   .then(res => {
        //     this.list = res.data
        //   })
      },
      // vue自己去初始化了选项式api
      created() {
        // 在created就可以拿了，比如data的数据，比如执行methods的方法
        // created里面就可以做数据请求了
        console.log("created", this.count);
      },

      // 挂载阶段
      // 挂载阶段也能做数据请求
      beforeMount() {
        // beforeMount的时候，页面上面还没有挂载元素上去
        // console.log("beforeMount", document.querySelector("h1"));
        console.log("beforeMount", this.$refs.h1);
      },
      // vue初始渲染，创建和插入dom节点
      mounted() {
        // mounted时所有元素都已经挂载结束了
        // 如果操作是跟dom相关的，只能在mounted里面做
        // 像一些echarts，amap等第三方插件的使用就只能在mounted里面
        console.log("mounted", document.querySelector("h1"));
        console.log("mounted", this.$refs.h1);
      },

      // 更新阶段
      // 更新阶段需要在页面的数据发生改变的时候才会执行
      // 更新前和更新后，不是表示数据更改的前后。这两个函数都是数据改变以后执行的
      beforeUpdate() {
        // 在页面重新渲染之前执行
        // console.log("beforeUpdate", this.count, this.$refs.p.innerHTML);
      },
      updated() {
        // 在页面重新渲染之后执行
        // 想拿到更新以后的dom节点的信息，那么只能在updated里面拿到
        // console.log("updated", this.count, this.$refs.p.innerHTML);
        // 不能在updated里面修改数据，会死循环
        // this.count++;
      },

      // 销毁阶段
      // 会在组件销毁的时候执行，动态组件/路由
      // 比如定时器，组件销毁的时候，定时器是不会被一起销毁（会影响性能）
      // 如果组件开启了定时器，不要忘记在组件销毁的时候关闭定时器
      // 除了定时器，websocket, js事件监听
      beforeUnmount() {
        console.log("beforeUnmount");
      },
      unmounted() {
        console.log("unmounted");
      }
      
    }).mount("#app")
  </script>
</body>
</html>